package com.ruoyi.common.config.serializer

import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.databind.BeanProperty
import com.fasterxml.jackson.databind.JsonMappingException
import com.fasterxml.jackson.databind.JsonSerializer
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.ser.ContextualSerializer
import com.ruoyi.common.annotation.Sensitive
import com.ruoyi.common.core.domain.model.LoginUser
import com.ruoyi.common.enums.DesensitizedType
import com.ruoyi.common.utils.SecurityUtils
import java.io.IOException
import java.util.*

/**
 * 数据脱敏序列化过滤
 *
 * @author ruoyi
 */
class SensitiveJsonSerializer : JsonSerializer<String?>(), ContextualSerializer {
    private var desensitizedType: DesensitizedType? = null
    @Throws(IOException::class)
    override fun serialize(value: String?, gen: JsonGenerator, serializers: SerializerProvider?) {
        if (desensitization()) {
            gen.writeString(value?.let { desensitizedType?.desensitizer()?.apply(it) })
        } else {
            gen.writeString(value)
        }
    }

    @Throws(JsonMappingException::class)
    override fun createContextual(prov: SerializerProvider, property: BeanProperty): JsonSerializer<*> {
        val annotation: Sensitive = property.getAnnotation(Sensitive::class.java)
        if (Objects.nonNull(annotation) && String::class.java== property.type.rawClass) {
            desensitizedType = annotation.desensitizedType
            return this
        }
        return prov.findValueSerializer(property.type, property)
    }

    /**
     * 是否需要脱敏处理
     */
    private fun desensitization(): Boolean {
        return try {
            val securityUser: LoginUser = SecurityUtils.loginUser
            // 管理员不脱敏
            !securityUser.user!!.isAdmin
        } catch (e: Exception) {
            true
        }
    }
}
